/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Container_Array_h
#define SBJ_Container_Array_h

#include <boost/noncopyable.hpp>

#include <stdexcept>

namespace SBJ
{

/*
Class: Array

The boost:array has a fixed size at compile time while std::vector
is a very dynamic variable sized array. Array implements
a very simple wrapper around a dynamically allocated but fixed size
array. In other words, the memory size is variable at construction.

Array promises to never move memory and does NOT provide
access to the underlying pointer.
*/

template < typename T >
class Array : private boost::noncopyable
{
public:
	typedef T value_type;
	typedef size_t size_type;
/*
	class iterator
	{
	public:
		iterator( const iterator& rhs ) : m_a( rhs.m_a ), m_i( rhs.m_i ) {}
		~iterator( void ) {}
		bool operator == ( const iterator& rhs ) const { return m_a == rhs.m_a && m_i == rhs.m_i; }
		iterator& operator = ( const iterator& rhs ) { m_a = rhs.m_a; m_i = rhs.m_i; return *this; }
		value_type& operator * ( void ) { return (*m_a)[ m_i ]; }
		value_type* operator -> ( void ) { return &(*m_a)[ m_i ]; }
		operator value_type* ( void ) { return &(*m_a)[ m_i ]; }
		iterator& operator ++ ( void ) { ++m_i; return *this; }
	private:
		friend Array;
		iterator( Array& array );
		Array* m_a;
		size_type m_i;
	};

	class const_iterator
	{
	public:
		const_iterator( const iterator& rhs ) : m_a( rhs.m_a ), m_i( rhs.m_i ) {}
		const_iterator( const const_iterator& rhs ) : m_a( rhs.m_a ), m_i( rhs.m_i ) {}
		~const_iterator( void ) {}
		bool operator == ( const const_iterator& rhs ) const { return m_a == rhs.m_a && m_i == rhs.m_i; }
		iterator& operator = ( const const_iterator& rhs ) { m_a = rhs.m_a; m_i = rhs.m_i; return *this; }
		const value_type& operator * ( void ) const { return (*m_a)[ m_i ]; }
		const value_typ* operator -> ( void ) const { return &(*m_a)[ m_i ]; }
		operator const value_type* ( void ) const { return &(*m_a)[ m_i ]; }
		iterator& operator ++ ( void ) { ++m_i; return *this; }
	private:
		friend Array;
		iterator( Array& array, size_type i );
		const Array* m_array;
		size_type m_i;
	};
*/
	Array( size_t s ) : m_s( s ), m_a( new T[ s ] ) {}

	~Array( void ) { delete[] m_a; }

	size_type size( void ) const { return m_s; }

	value_type& operator [] ( size_t i ) { return m_a[ i ]; }

	value_type& at( size_type i ) { if ( i >= m_s ) throw std::out_of_range( "Array" ); return m_a[ i ]; }

	const value_type& operator [] ( size_t i ) const { return m_a[ i ]; }

	const value_type& at( size_type i ) const { if ( i >= m_s ) throw std::out_of_range( "Array" ); return m_a[ i ]; }
/*
	iterator begin( void ) { return iterator( *this, 0 ); }

	const_iterator begin( void ) const { return const_iterator( *this, 0 ); }

	iterator end( void ) { return iterator( *this, m_s ); }

	const_iterator end( void ) const { return const_iterator( *this, m_s ); } 
*/
private:
	const size_type m_s;
	T* m_a;
};

}

#endif
